6.5.1 Sqlx

Sqlx是一个第三方库,它为 database/sql 包提供了一系列非常有用的扩展功能。因为Sqlx和 database/sql 包使用的是相同的接口,所以Sqlx能够很好地兼容使用 database/sql 包的程序,除此之外,Sqlx还提供了以下这些额外的功能:

  • 通过结构标签(struct tag)将数据库记录(即行)封装为结构、映射或者切片;
  • 为预处理语句提供具名参数支持。

代码清单6-17展示了如何使用Sqlx及其提供的 StructScan 方法来对论坛程序进行简化。另外别忘了,在使用Sqlx库之前,需要先通过执行以下命令来获取这个库:

go get "github.com/jmoiron/sqlx"

代码清单6-17 使用 Sqlx 重新实现论坛程序

package main
import (
  "fmt"
  "github.com/jmoiron/sqlx"
  _ "github.com/lib/pq"
)
type Post struct {
  Id   int
  Content string
  AuthorName string `db: author`
}
var Db *sqlx.DB
func init() {
  var err error
  Db, err = sqlx.Open("postgres", "user=gwp dbname=gwp password=gwp
  ➥sslmode=disable")
  if err != nil {
    panic(err)
  }
}
func GetPost(id int) (post Post, err error) {
  post = Post{}
  err = Db.QueryRowx("select id, content, author from posts where id =
  ➥$1", id).StructScan(&post)
  if err != nil {
    return
  }
  return
}
func (post *Post) Create() (err error) {
  err = Db.QueryRow("insert into posts (content, author) values ($1, $2)
  ➥returning id", post.Content, post.AuthorName).Scan(&post.Id)
  return
}
func main() {
  post := Post{Content: "Hello World!", AuthorName: "Sau Sheong"}
  post.Create()
  fmt.Println(post)  ❶
}

❶ {1 Hello World! Sau Sheong}}

代码清单中的加粗代码展示了使用Sqlx与使用 database/sql 之间的区别,而其余的则是一些我们之前已经看到过的代码。首先,程序现在不再导入 database/sql 包,而是导入 github.com/jmoiron/sqlx 包。在默认情况下, StructScan 会根据结构字段名的英文小写体,将结构中的字段映射至表中的列。为了演示如何将指定的表列映射至指定的结构字段,代码清单6-17将原来的 Author 字段修改成了 AuthorName 字段,然后通过结构标签来指示Sqlx应该从 author 列里面获取 AuthorName 字段的数据。本书将在第7章对结构标签做进一步的说明。

程序现在也会使用 sqlx.DB 结构来代替之前的 sql.DB 结构,这两种结构非常相似,只不过 sqlx.DB 包含了诸如 Queryx 以及 QueryRowx 等额外的方法。

修改之后的 GetPost 函数也使用 QueryRowx 代替了之前的 QueryRow 。 QueryRowx 在执行之后将返回 Rowx 结构,这种结构拥有 StructScan 方法,该方法可以将列自动地映射到相应的字段里面。另一方面,对于 Create 方法,我们还是跟之前一样,使用 QueryRow 方法进行查询。

除了这里提到的特性之外,Sqlx还拥有其他一些有趣的特性,感兴趣的读者可以通过访问Sqlx的GitHub页面来了解:https://github.com/jmoiron/sqlx。

Sqlx是一个有趣并且有用的 database/sql 扩展,但它支持的特性并不多。与此相反,我们接下来要学习的Gorm库不仅把 database/sql 包隐藏了起来,它还提供了一个完整且强大的ORM机制来代替 database/sql 包。

results matching ""

    No results matching ""